package mosdi.tests;

import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import junit.framework.TestCase;
import mosdi.fa.Alphabet;
import mosdi.matching.PositionWeightMatrix;
import mosdi.util.Iupac;
import mosdi.util.IupacStringConstraints;
import mosdi.util.iterators.IupacPatternIterator;

public class PositionWeightMatrixTest extends TestCase {
	private final static double[][] matrix =
	{{-0.4639738697821571,0.6346384188859526,-0.4424676645611934,0.1382015325720616,-0.4639738697821571,-0.4639738697821571},
		{0.7556671161544013,-0.3429451725137084,-0.2595635635746574,0.36101292415045255,-0.3429451725137084,-0.3429451725137084},
		{-0.343118938581228,-0.343118938581228,0.33909917144652696,-0.2399347023459973,-0.343118938581228,0.7554933500868817},
		{-0.46448260881257547,-0.46448260881257547,0.18421280917653615,-0.4219229943937795,0.6341296798555343,-0.46448260881257547}
	};
	private final static Alphabet iupacAlphabet = Alphabet.getIupacAlphabet();
	private final static Alphabet dnaAlphabet = Alphabet.getDnaAlphabet();

	public static void assertIupacGeneration(PositionWeightMatrix pwm, double threshold) {
		Set<String> set = new HashSet<String>();
		List<int[]> l = pwm.toGeneralizedStrings(threshold, Iupac.asGeneralizedAlphabet());
		for (int[] s : l) {
			Iterator<int[]> iter = Iupac.patternInstanceIterator(s);
			while (iter.hasNext()) {
				String string = dnaAlphabet.buildString(iter.next());
				assertFalse(set.contains(string));
				set.add(string);
			}
		}
		// System.out.println(set);
		Iterator<int[]> iter = new IupacPatternIterator(pwm.width(), new IupacStringConstraints(pwm.width(), false));
		while (iter.hasNext()) {
			String string = iupacAlphabet.buildString(iter.next());
			double score = pwm.score(dnaAlphabet.buildIndexArray(string));
			boolean valid = score>=threshold;
			// System.out.println(string+" "+score+" "+valid);
			assertTrue(valid == set.contains(string));
		}
	}
	
	public void testIupacGenerator() {
		PositionWeightMatrix pwm = new PositionWeightMatrix(matrix);
		assertIupacGeneration(pwm, 3.257229);
		assertIupacGeneration(pwm, 20);
		assertIupacGeneration(pwm, -20);
		assertIupacGeneration(pwm, 0.0);
		assertIupacGeneration(pwm, 1.4);
		assertIupacGeneration(pwm, 2.3);
	}

}
